package com.faceless.ffmpegaudioaroid.acitvity;

import android.annotation.SuppressLint;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.faceless.ffmpegaudioaroid.R;
import com.faceless.ffmpegaudioaroid.base.Constant;
import com.faceless.ffmpegaudioaroid.base.OnGlobalListener;
import com.faceless.ffmpegaudioaroid.model.FileBean;
import com.faceless.ffmpegaudioaroid.utils.FileUtil;
import com.faceless.ffmpegaudioaroid.utils.RecyclerViewUtils;
import com.faceless.ffmpegmedia.FFmpegCmd;
import com.faceless.ffmpegmedia.utils.FFmpegUtil;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * 使用ffmpeg处理音频
 *Created by victorliu on 2018/10/16.
 */
public class AudioHandleActivity extends AppCompatActivity implements View.OnClickListener{
    private final static String TAG = AudioHandleActivity.class.getSimpleName();
    private final static String PATH = Environment.getExternalStorageDirectory().getPath();
    private String srcFile = PATH + File.separator + "22.aac";
    private String appendFile = PATH + File.separator + "99.aac";
    private final static int MSG_BEGIN = 11;
    private final static int MSG_FINISH = 12;
    private ProgressBar progress_audio;

    private Button start_tv;
    private RecyclerView recyclerView;
    private Button btn_play;
    private TextView tv_path;
    //线程操作
    private ExecutorService mExecutorService;
    //录音API
    private MediaRecorder mMediaRecorder;
    //录音开始时间与结束时间
    private long startTime, endTime;
    //录音所保存的文件
    private File mAudioFile;
    //文件列表数据
    private ArrayList<FileBean> dataList;
    //录音文件保存位置
    private String mFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/links/";
    //当前是否正在播放
    private volatile boolean isPlaying;
    //播放音频文件API
    private MediaPlayer mediaPlayer;
    //保存地址
    String concatFile;
    BaseQuickAdapter baseQuickAdapter;
    //使用Handler更新UI线程
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case MSG_BEGIN:
                    progress_audio.setVisibility(View.VISIBLE);
                    setGone();
                    break;
                case MSG_FINISH:
                    progress_audio.setVisibility(View.GONE);
                    setVisible();
                    btn_play.setVisibility(View.VISIBLE);
                    btn_play.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            startPlay(new File(concatFile));
                        }
                    });
                    tv_path.setVisibility(View.VISIBLE);
                    tv_path.setText("合成文件地址"+concatFile);
                    break;
                case Constant.RECORD_SUCCESS:
                    //录音成功，展示数据
                   baseQuickAdapter.notifyDataSetChanged();
                    break;
                //录音失败
                case Constant.RECORD_FAIL:
                    showToastMsg(getString(R.string.record_fail));
                    break;
                //录音时间太短
                case Constant.RECORD_TOO_SHORT:
                    showToastMsg(getString(R.string.time_too_short));
                    break;
                case Constant.PLAY_COMPLETION:
                    showToastMsg(getString(R.string.play_over));
                    break;
                case Constant.PLAY_ERROR:
                    showToastMsg(getString(R.string.play_error));
                    break;
                default:

                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_audio_handle);
        initView();
        initEvents();
    }
    private void initView() {
        //录音及播放要使用单线程操作
        mExecutorService = Executors.newSingleThreadExecutor();
        dataList = new ArrayList<>();
        progress_audio =findViewById(R.id.progress_audio);
        start_tv =findViewById(R.id.start_tv);
        recyclerView =findViewById(R.id.rv_list);
        btn_play=findViewById(R.id.btn_play);
        tv_path=findViewById(R.id.tv_path);
        findViewById(R.id.btn_transform).setOnClickListener(this);
        findViewById(R.id.btn_cut).setOnClickListener(this);
        findViewById(R.id.btn_concat).setOnClickListener(this);
        baseQuickAdapter= RecyclerViewUtils.initLiner(AudioHandleActivity.this, recyclerView, R.layout.file_item_layout, dataList, new OnGlobalListener() {
            @Override
            public <T> void logic(final BaseViewHolder helper, T item) {
                final FileBean bean= (FileBean) item;
                helper.setText(R.id.item_tv, "录音文件：" + bean.getFile().getAbsolutePath() + "\n录音时长：" + bean.getFileLength());
                helper.setOnClickListener(R.id.btn_delete, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dataList.remove(bean);
                        FileUtil.delFile(bean.getFile().getAbsolutePath());
                        baseQuickAdapter.notifyDataSetChanged();
                    }
                });
            }
        }, new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {

            }
        });
    }
    private void setVisible() {
//        findViewById(R.id.btn_transform).setVisibility(View.VISIBLE);
//        findViewById(R.id.btn_cut).setVisibility(View.VISIBLE);
        findViewById(R.id.btn_concat).setVisibility(View.VISIBLE);
    }
    private void setGone() {
        findViewById(R.id.btn_transform).setVisibility(View.GONE);
        findViewById(R.id.btn_cut).setVisibility(View.GONE);
        findViewById(R.id.btn_concat).setVisibility(View.GONE);
    }
    protected void initEvents() {
        //类似微信等应用按住说话进行录音，所以用OnTouch事件
        this.start_tv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    //按下操作
                    case MotionEvent.ACTION_DOWN:
                        //安卓6.0以上录音相应权限处理
                        startRecord();
                        break;
                    //松开操作
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_UP:
                        stopRecord();
                        break;
                }
                //对OnTouch事件做了处理，返回true
                return true;
            }
        });
    }
    /**
     * @description 开始播放音频文件
     * @author victorliu
     * @time 2018/10/17 14:20
     */
    private void startRecord() {
        start_tv.setText(R.string.stop_by_up);
        start_tv.setBackgroundResource(R.drawable.bg_gray_round);
        //异步任务执行录音操作
        mExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                //播放前释放资源
                releaseRecorder();
                //执行录音操作
                recordOperation();
            }
        });
    }
    /**
     * @description 开始播放音频文件
     * @author victorliu
     * @time 2018/10/17 12:15
     */
    private void recordOperation() {
        //创建MediaRecorder对象
        mMediaRecorder = new MediaRecorder();
        //创建录音文件,.m4a为MPEG-4音频标准的文件的扩展名
        mAudioFile = new File(mFilePath + System.currentTimeMillis() + ".acc");
        //创建父文件夹
        mAudioFile.getParentFile().mkdirs();
        try {
            //创建文件
            mAudioFile.createNewFile();
            //配置mMediaRecorder相应参数
            //从麦克风采集声音数据
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            //设置保存文件格式为MP4
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
            //设置采样频率,44100是所有安卓设备都支持的频率,频率越高，音质越好，当然文件越大
            mMediaRecorder.setAudioSamplingRate(44100);
            //设置声音数据编码格式,音频通用格式是AAC
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            //设置编码频率
            mMediaRecorder.setAudioEncodingBitRate(96000);
            //设置录音保存的文件
            mMediaRecorder.setOutputFile(mAudioFile.getAbsolutePath());
            //开始录音
            mMediaRecorder.prepare();
            mMediaRecorder.start();
            //记录开始录音时间
            startTime = System.currentTimeMillis();
        } catch (Exception e) {
            e.printStackTrace();
            recordFail();
        }
    }
    /**
     * @description 开始播放音频文件
     * @author victorliu
     * @time 2018/10/17 13:10
     */
    private void recordFail() {
        mAudioFile = null;
        mHandler.sendEmptyMessage(Constant.RECORD_FAIL);
    }
    /**
     * @description 开始播放音频文件
     * @author victorliu
     * @time 2018/10/17 13:10
     */
    private void releaseRecorder() {
        if (null != mMediaRecorder) {
            mMediaRecorder.release();
            mMediaRecorder = null;
        }
    }
    /**
     * @description 开始播放音频文件
     * @author victorliu
     * @time 2018/10/17 15:56
     */
    private void stopRecord() {
        if(mMediaRecorder!=null){
            start_tv.setText(R.string.speak_by_press);
            start_tv.setBackgroundResource(R.drawable.bg_white_round);
            //设置后不会崩
            mMediaRecorder.setOnErrorListener(null);
            mMediaRecorder.setPreviewDisplay(null);
            try {
                mMediaRecorder.stop();
            } catch (IllegalStateException e) {
                Log.w("Yixia", "stopRecord", e);
            } catch (RuntimeException e) {
                Log.w("Yixia", "stopRecord", e);
            } catch (Exception e) {
                Log.w("Yixia", "stopRecord", e);
            }

            //记录停止时间
            endTime = System.currentTimeMillis();
            //录音时间处理，比如只有大于2秒的录音才算成功
            int time = (int) ((endTime - startTime) / 1000);
            if (time >= 3) {
                //录音成功,添加数据
                FileBean bean = new FileBean();
                bean.setFile(mAudioFile);
                bean.setFileLength(time);
                dataList.add(bean);
                //录音成功,发Message
                mHandler.sendEmptyMessage(Constant.RECORD_SUCCESS);
            } else {
                mAudioFile = null;
                mHandler.sendEmptyMessage(Constant.RECORD_TOO_SHORT);
            }
            //录音完成释放资源
            releaseRecorder();
        }else {
        }
    }
    /**
     * @description 开始播放音频文件
     * @author victorliu
     * @time 2018/10/17 16:56
     */
    private void startPlay(File mFile) {
        try {
            if(mediaPlayer==null){
                //初始化播放器
                mediaPlayer = new MediaPlayer();
                //设置播放音频数据文件
                mediaPlayer.setDataSource(mFile.getAbsolutePath());
                //设置播放监听事件
                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mediaPlayer) {
                        //播放完成
                        playEndOrFail(true);
                    }
                });
                //播放发生错误监听事件
                mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    @Override
                    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                        playEndOrFail(false);
                        return true;
                    }
                });
                //播放器音量配置
                mediaPlayer.setVolume(1, 1);
                //是否循环播放
                mediaPlayer.setLooping(false);
                //准备及播放
                mediaPlayer.prepare();
                mediaPlayer.start();
            }else {
                if(mediaPlayer.isPlaying()){

                }else {
                    //初始化播放器
                    mediaPlayer = new MediaPlayer();
                    //设置播放音频数据文件
                    mediaPlayer.setDataSource(mFile.getAbsolutePath());
                    //设置播放监听事件
                    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mediaPlayer) {
                            //播放完成
                            playEndOrFail(true);
                        }
                    });
                    //播放发生错误监听事件
                    mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                        @Override
                        public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                            playEndOrFail(false);
                            return true;
                        }
                    });
                    //播放器音量配置
                    mediaPlayer.setVolume(1, 1);
                    //是否循环播放
                    mediaPlayer.setLooping(false);
                    //准备及播放
                    mediaPlayer.prepare();
                    mediaPlayer.start();
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
            //播放失败正理
            playEndOrFail(false);
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mediaPlayer!=null){
            mediaPlayer.setOnCompletionListener(null);
            mediaPlayer.setOnErrorListener(null);
            mediaPlayer.stop();
            mediaPlayer.reset();
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    /**
     * @description 开始播放音频文件
     * @author victorliu
     * @time 2018/10/17 16:58
     */
    private void playEndOrFail(boolean isEnd) {
        isPlaying = false;
        if (isEnd) {
            mHandler.sendEmptyMessage(Constant.PLAY_COMPLETION);
        } else {
            mHandler.sendEmptyMessage(Constant.PLAY_ERROR);
        }
        if (null != mediaPlayer) {
            mediaPlayer.setOnCompletionListener(null);
            mediaPlayer.setOnErrorListener(null);
            mediaPlayer.stop();
            mediaPlayer.reset();
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }
    @Override
    public void onClick(View v) {
        int handleType;
        switch (v.getId()){
            case R.id.btn_transform:

                handleType = 0;
                break;
            case R.id.btn_cut:
                handleType = 1;
                break;
            case R.id.btn_concat:
                handleType = 2;
                break;
            default:
                handleType = 0;
                break;
        }
        doHandleAudio(handleType);
    }
    /**
     * 调用ffmpeg处理音频
     * @param handleType handleType
     */
    private void doHandleAudio(int handleType){
        String[] commandLine = null;
        switch (handleType){
            case 0://转码
                String transformFile = PATH + File.separator + "99.aac";
                commandLine = FFmpegUtil.transformAudio(srcFile, transformFile);
                break;
            case 1://剪切
                String cutFile = PATH + File.separator + "11.aac";
                commandLine = FFmpegUtil.cutAudio(srcFile, 10, 15, cutFile);
                break;
            case 2://合并，支持MP3、AAC、AMR等，不支持PCM裸流，不支持WAV（PCM裸流加音频头）
                concatFile = PATH + File.separator + "ImitateShow.aac";
                String uri="ffmpeg -i concat:";
                if(dataList.size()>1){
                    for (int i=0;i<dataList.size();i++){
                        uri+=dataList.get(i).getFile().getAbsolutePath()+"|";
                    }
                    String contactUri=uri.substring(0,uri.length() - 1);
                    contactUri+=" -acodec copy "+concatFile;
                    commandLine = FFmpegUtil.concatAudio(contactUri);
                }else {
                    showToastMsg("无录制音频或音频文件小于2");
                }
                break;
            case 3://混合
                String mixFile = PATH + File.separator + "mix.aac";
                commandLine = FFmpegUtil.mixAudio(srcFile, appendFile, mixFile);
                break;
            default:
                break;
        }
        executeFFmpegCmd(commandLine);
    }
    /**
     * 执行ffmpeg命令行
     * @param commandLine commandLine
     */
    private void executeFFmpegCmd(final String[] commandLine){
        if(commandLine == null){
            return;
        }
        FFmpegCmd.execute(commandLine, new FFmpegCmd.OnHandleListener() {
            @Override
            public void onBegin() {
                Log.i(TAG, "handle audio onBegin...");
                mHandler.obtainMessage(MSG_BEGIN).sendToTarget();
            }

            @Override
            public void onEnd(int result) {
                Log.i(TAG, "handle audio onEnd...");
                mHandler.obtainMessage(MSG_FINISH).sendToTarget();

            }
        });
    }
    protected void showToastMsg(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }
}
